package cc.ufinity.networkdiagnose.manager;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;

import cc.ufinity.networkdiagnose.manager.Task.FTPTask;
import cc.ufinity.networkdiagnose.manager.Task.HttpTask;
import cc.ufinity.networkdiagnose.manager.Task.PingTask;
import cc.ufinity.networkdiagnose.util.StringUtils;

import android.os.Environment;
import android.util.Log;
import android.util.Xml;

public class PullTaskParser implements TaskParser {

    @Override
    public List<APInfo> parseAPInfo(InputStream is) throws Exception {
        List<APInfo> list = null;
        APInfo info = null;
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(is, "UTF-8");
        int type = parser.getEventType();
        while (type != XmlPullParser.END_DOCUMENT) {
            switch (type) {
            case XmlPullParser.START_DOCUMENT:
                list = new ArrayList<APInfo>();
                break;
            case XmlPullParser.START_TAG:
                String tag = parser.getName();
                if ("APINFO".equals(tag)) {
                    info = new APInfo();
                } else if ("APName".equals(tag)) {
                    type = parser.next();
                    info.name = parser.getText();
                } else if ("APMac".equals(tag)) {
                    type = parser.next();
                    info.mac = parser.getText();
                }
                break;
            case XmlPullParser.END_TAG:
                tag = parser.getName();
                if ("APINFO".equals(tag)) {
                    list.add(info);
                    info = null;
                }
                break;
            }
            type = parser.next();
        }
        is.close();
        return list;
    }

    @Override
    public List<Task> parse(InputStream is) throws Exception {
        List<Task> tasks = null;
        List<PingTask> pingTasks = null;
        List<HttpTask> httpTasks = null;
        List<FTPTask> ftpTasks = null;
        Task task = null;
        PingTask pingTask = null;
        HttpTask httpTask = null;
        FTPTask ftpTask = null;
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(is, "UTF-8");
        // parser.se
        int type = parser.getEventType();
        while (type != XmlPullParser.END_DOCUMENT) {
            switch (type) {
            case XmlPullParser.START_DOCUMENT:
                tasks = new ArrayList<Task>();
                break;
            case XmlPullParser.START_TAG:
                String tag = parser.getName();
                if (tag.equals("Task")) {
                    task = new Task();
                    pingTasks = new ArrayList<PingTask>();
                    httpTasks = new ArrayList<HttpTask>();
                    ftpTasks = new ArrayList<FTPTask>();
                } else if (parser.getName().equals("TaskID")) {
                    type = parser.next();
                    task.id = StringUtils.parseInt(parser.getText());
                } else if ("TaskMan".equals(tag)) {
                    type = parser.next();
                    task.taskMan = parser.getText();
                } else if ("TaskPhone".equals(tag)) {
                    type = parser.next();
                    task.taskPhone = parser.getText();
                } else if ("TaskName".equals(tag)) {
                    type = parser.next();
                    task.taskName = parser.getText();
                } else if ("APName".equals(tag)) {
                    type = parser.next();
                    task.apName = parser.getText();
                } else if ("TaskType".equals(tag)) {
                    type = parser.next();
                    task.taskType = parser.getText();
                } else if ("TaskDes".equals(tag)) {
                    type = parser.next();
                    task.taskDes = parser.getText();
                } else if ("PingAddress".equals(tag)) {
                    type = parser.next();
                    String pingAddress = parser.getText();
                    pingTask = task.newPingTask(pingAddress);
                } else if ("HttpSite".equals(tag)) {
                    type = parser.next();
                    String httpAddress = parser.getText();
                    httpTask = task.newHttpTask(httpAddress);
                } else if ("FTPAddress".equals(tag)) {
                    type = parser.next();
                    String ftpAddress = parser.getText();
                    ftpTask = task.newFTPTask(ftpAddress);
                    // task.ftpTasks = parseFTPTask(ftpAddress,task);
                } else if ("TestCount".equals(tag)) {
                    type = parser.next();
                    task.testCount = StringUtils.parseInt(parser.getText());
                } else if ("Remark".equals(tag)) {
                    type = parser.next();
                    task.remark = parser.getText();
                }
                break;
            case XmlPullParser.END_TAG:
                tag = parser.getName();
                if ("Task".equals(tag)) {
                    task.ftpTasks = ftpTasks;
                    task.pingTasks = pingTasks;
                    task.httpTasks = httpTasks;
                    tasks.add(task);
                    task = null;
                } else if ("PingAddress".equals(tag)) {
                    pingTasks.add(pingTask);
                    pingTask = null;
                } else if ("HttpSite".equals(tag)) {
                    httpTasks.add(httpTask);
                    httpTask = null;
                } else if ("FTPAddress".equals(tag)) {
                    ftpTasks.add(ftpTask);
                    ftpTask = null;
                }
                break;
            }
            type = parser.next();
        }
        is.close();
        return tasks;
    }

    public String XmlFileCreator(Task task) {

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmsss");
        Date curDate = new Date(System.currentTimeMillis());
        String fileName = formatter.format(curDate) + ".xml";

        File newxmlfile = new File(Environment.getExternalStorageDirectory() + "/" + fileName);
        Log.d("XmlFileCreator", "新的XML文件：" + newxmlfile.getName());
        try {
            if (!newxmlfile.exists())
                newxmlfile.createNewFile();
        } catch (IOException e) {
            Log.e("XmlFileCreator", "创建XML文件出错：", e);
            return null;
        }
        // we have to bind the new file with a FileOutputStream
        FileOutputStream fileos = null;
        try {
            fileos = new FileOutputStream(newxmlfile);
        } catch (FileNotFoundException e) {
            Log.e("XmlFileCreator", "写入XML文件出错：", e);
            return null;
        }
        // we create a XmlSerializer in order to write xml data
        XmlSerializer serializer = Xml.newSerializer();
        try {
            // we set the FileOutputStream as output for the serializer, using
            // UTF-8 encoding
            serializer.setOutput(fileos, "UTF-8");
            // Write <?xml declaration with encoding (if encoding not null) and
            // standalone flag (if standalone not null)
            serializer.startDocument(null, Boolean.valueOf(true));
            // set indentation option
            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
            // start a tag called "root"
            DecimalFormat df = new DecimalFormat("#0.000");
            serializer.startTag(null, "Root");
            serializer.startTag(null, "TestResultInfo");
            serializer.startTag(null, "TaskID");
            serializer.text(String.valueOf(task.id));
            serializer.endTag(null, "TaskID");
            serializer.startTag(null, "NetType");
            serializer.text(task.netType);
            serializer.endTag(null, "NetType");
            serializer.startTag(null, "TestPhone");
            serializer.text(task.testPhone);
            serializer.endTag(null, "TestPhone");
            serializer.startTag(null, "Mac");
            serializer.text(task.mac);
            serializer.endTag(null, "Mac");
            serializer.startTag(null, "Lac");
            serializer.text(task.lac);
            serializer.endTag(null, "Lac");
            serializer.startTag(null, "Ci");
            serializer.text(task.ci);
            serializer.endTag(null, "Ci");
            serializer.startTag(null, "SiteDescript");
            serializer.text(task.taskAddress);
            serializer.endTag(null, "SiteDescript");
            serializer.startTag(null, "StartTime");
            serializer.text(task.startTime);
            serializer.endTag(null, "StartTime");
            serializer.startTag(null, "EndTime");
            serializer.text(task.endTime);
            serializer.endTag(null, "EndTime");

            serializer.startTag(null, "Longitute");
            serializer.text(task.gps.Longitute);
            serializer.endTag(null, "Longitute");
            serializer.startTag(null, "Latitute");
            serializer.text(task.gps.Latitute);
            serializer.endTag(null, "Latitute");

            serializer.startTag(null, "RelevanceAPAvgTime");
            serializer.text(task.relevanceAPAvgTime);
            serializer.endTag(null, "RelevanceAPAvgTime");
            serializer.startTag(null, "RelevanceAPSuccessRate");
            serializer.text(task.relevanceAPSuccessRate);
            serializer.endTag(null, "RelevanceAPSuccessRate");

            serializer.startTag(null, "RSSI");
            //String fieldstrength = task.wlan == null ? "" : task.wlan.fieldstrength;
            serializer.text(task.rssi);
            serializer.endTag(null, "RSSI");

            serializer.startTag(null, "SNR");
            serializer.text("-1");
            serializer.endTag(null, "SNR");

            serializer.startTag(null, "WebDelay");
            serializer.text(task.webDelay);
            serializer.endTag(null, "WebDelay");

            serializer.startTag(null, "WebSuccessRate");
            serializer.text(task.webSuccessRate);
            serializer.endTag(null, "WebSuccessRate");

            serializer.startTag(null, "WebOffSuccessRate");
            serializer.text(task.webOffSuccessRate);
            serializer.endTag(null, "WebOffSuccessRate");

            serializer.startTag(null, "PeapDelay");
            serializer.text("0");
            serializer.endTag(null, "PeapDelay");

            serializer.startTag(null, "PeapOffSuccessRate");
            serializer.text("0");
            serializer.endTag(null, "PeapOffSuccessRate");

            serializer.startTag(null, "SimSuccessRate");
            serializer.text("0");
            serializer.endTag(null, "SimSuccessRate");

            serializer.startTag(null, "SimOffSuccessRate");
            serializer.text("0");
            serializer.endTag(null, "SimOffSuccessRate");

            List<HttpTask> httpTasks = task.httpTasks;
            if (httpTasks != null) {
                Iterator<HttpTask> iterHttp = httpTasks.iterator();
                double delays = 0.0;
                // double speeds = 0.0;
                int failedTimes = 0;
                int num = httpTasks.size();
                while (iterHttp.hasNext()) {
                    HttpTask httpTask = iterHttp.next();
                    delays = delays + Double.parseDouble(httpTask.delay);
                    failedTimes += httpTask.failedTimes;
                }
                float successRate = ((float) (num * task.testCount - failedTimes) / (num * task.testCount)) * 100;
                serializer.startTag(null, "HttpAnwerDelay");
                serializer.text(String.valueOf(df.format(delays / num)));
                serializer.endTag(null, "HttpAnwerDelay");

                serializer.startTag(null, "HttpCallSuccessRate");
                serializer.text(String.valueOf(successRate));
                serializer.endTag(null, "HttpCallSuccessRate");
            } else {
                serializer.startTag(null, "HttpAnwerDelay");
                serializer.text("0");
                serializer.endTag(null, "HttpAnwerDelay");

                serializer.startTag(null, "HttpCallSuccessRate");
                serializer.text("0");
                serializer.endTag(null, "HttpCallSuccessRate");
            }

            List<PingTask> pingTasks = task.pingTasks;
            if (pingTasks != null) {
                Iterator<PingTask> iterPing = pingTasks.iterator();
                float bytes = 0;
                float times = 0;
                float ttls = 0;
                while (iterPing.hasNext()) {
                    PingTask pingTask = iterPing.next();
                    bytes = bytes + StringUtils.parseFloat(pingTask.bytes);
                    times = times + StringUtils.parseFloat(pingTask.time);
                    ttls = ttls + StringUtils.parseFloat(pingTask.ttl);
                }
                int num = pingTasks.size();

                serializer.startTag(null, "PingAvgDelay");
                serializer.text(String.valueOf(df.format((float) ((float) times / 1000) / num)));
                serializer.endTag(null, "PingAvgDelay");

                serializer.startTag(null, "PingPacketLoss");
                serializer.text("0");
                serializer.endTag(null, "PingPacketLoss");
            } else {
                serializer.startTag(null, "PingAvgDelay");
                serializer.text("0");
                serializer.endTag(null, "PingAvgDelay");

                serializer.startTag(null, "PingPacketLoss");
                serializer.text("0");
                serializer.endTag(null, "PingPacketLoss");
            }

            List<FTPTask> ftpTasks = task.ftpTasks;
            if (ftpTasks != null) {
                Iterator<FTPTask> iterFTP = ftpTasks.iterator();
                double loginTimes = 0.0;
                double upRates = 0.0;
                double downRates = 0.0;
                while (iterFTP.hasNext()) {
                    FTPTask ftpTask = iterFTP.next();
                    loginTimes = loginTimes + ftpTask.loginTime;
                    upRates = upRates + Double.parseDouble(ftpTask.upRate);
                    downRates = downRates + Double.parseDouble(ftpTask.downRate);
                }
                int num = ftpTasks.size();
                serializer.startTag(null, "FTPUpSuccessRate");
                serializer.text("100");
                serializer.endTag(null, "FTPUpSuccessRate");

                serializer.startTag(null, "FTPDownSuccessRate");
                serializer.text("100");
                serializer.endTag(null, "FTPDownSuccessRate");

                serializer.startTag(null, "FTPDownAvgSuccessRate");
                serializer.text(String.valueOf(df.format(downRates / num)));
                serializer.endTag(null, "FTPDownAvgSuccessRate");

                serializer.startTag(null, "FTPUpAvgSuccessRate");
                serializer.text(String.valueOf(df.format(upRates / num)));
                serializer.endTag(null, "FTPUpAvgSuccessRate");
            } else {
                serializer.startTag(null, "FTPUpSuccessRate");
                serializer.text("0");
                serializer.endTag(null, "FTPUpSuccessRate");

                serializer.startTag(null, "FTPDownSuccessRate");
                serializer.text("0");
                serializer.endTag(null, "FTPDownSuccessRate");

                serializer.startTag(null, "FTPDownAvgSuccessRate");
                serializer.text("0");
                serializer.endTag(null, "FTPDownAvgSuccessRate");

                serializer.startTag(null, "FTPUpAvgSuccessRate");
                serializer.text("0");
                serializer.endTag(null, "FTPUpAvgSuccessRate");
            }

            serializer.startTag(null, "UserIsolateSuccessRate");
            serializer.text(task.userIsolateSuccessRate);
            serializer.endTag(null, "UserIsolateSuccessRate");

            serializer.startTag(null, "UserRoamSuccessRate");
            serializer.text(task.userRoamSuccessRate);
            serializer.endTag(null, "UserRoamSuccessRate");

            serializer.startTag(null, "Time");
            serializer.text("0");
            serializer.endTag(null, "Time");

            /*
             * serializer.startTag(null, "LoginTime");
             * serializer.text(String.valueOf(df.format(loginTimes / num)));
             * serializer.endTag(null, "LoginTime"); serializer.startTag(null,
             * "UpRate"); serializer.text(String.valueOf(df.format(upRates /
             * num))); serializer.endTag(null, "UpRate");
             * serializer.startTag(null, "DownRate");
             * serializer.text(String.valueOf(df.format(downRates / num)));
             * serializer.endTag(null, "DownRate"); serializer.endTag(null,
             * "FTP"); // start HTTP Task Result serializer.startTag(null,
             * "HTTP"); List<HttpTask> httpTasks = task.httpTasks;
             * Iterator<HttpTask> iterHttp = httpTasks.iterator(); double delays
             * = 0.0; double speeds = 0.0; while (iterHttp.hasNext()) { HttpTask
             * httpTask = iterHttp.next(); delays = delays +
             * Double.parseDouble(httpTask.delay); speeds = speeds +
             * Double.parseDouble(httpTask.speed); } num = httpTasks.size();
             * serializer.startTag(null, "NetDelay");
             * serializer.text(String.valueOf(df.format(delays / num)));
             * serializer.endTag(null, "NetDelay"); serializer.startTag(null,
             * "DownSpeed"); serializer.text(String.valueOf(df.format(speeds /
             * num))); serializer.endTag(null, "DownSpeed");
             * serializer.endTag(null, "HTTP"); // start PING Task Result
             * serializer.startTag(null, "PING"); List<PingTask> pingTasks =
             * task.pingTasks; Iterator<PingTask> iterPing =
             * pingTasks.iterator(); float bytes = 0; float times = 0; float
             * ttls = 0; while (iterPing.hasNext()) { PingTask pingTask =
             * iterPing.next(); bytes = bytes +
             * StringUtils.parseFloat(pingTask.bytes); times = times +
             * StringUtils.parseFloat(pingTask.time); ttls = ttls +
             * StringUtils.parseFloat(pingTask.ttl); } num = pingTasks.size();
             * serializer.startTag(null, "ByteNo");
             * serializer.text(String.valueOf(df.format(bytes / num)));
             * serializer.endTag(null, "ByteNo"); serializer.startTag(null,
             * "Time"); serializer.text(String.valueOf(df .format((float)
             * ((float) times / 1000) / num))); serializer.endTag(null, "Time");
             * serializer.startTag(null, "TTL");
             * serializer.text(String.valueOf(df.format(ttls / num)));
             * serializer.endTag(null, "TTL"); serializer.endTag(null, "PING");
             * 
             * serializer.startTag(null, "GSM"); serializer.startTag(null,
             * "NetType"); serializer.text(task.gsm.netType);
             * serializer.endTag(null, "NetType"); serializer.startTag(null,
             * "LAC"); serializer.text(task.gsm.lac); serializer.endTag(null,
             * "LAC"); serializer.startTag(null, "CI");
             * serializer.text(task.gsm.ci); serializer.endTag(null, "CI");
             * serializer.startTag(null, "Fieldstrength");
             * serializer.text(task.gsm.fieldstrength); serializer.endTag(null,
             * "Fieldstrength"); serializer.startTag(null, "RSSI");
             * serializer.text(task.gsm.rssi); serializer.endTag(null, "RSSI");
             * serializer.startTag(null, "BER"); serializer.text(task.gsm.ber);
             * serializer.endTag(null, "BER"); serializer.endTag(null, "GSM");
             * 
             * serializer.startTag(null, "TD"); serializer.startTag(null,
             * "NetType"); serializer.text(task.td.netType);
             * serializer.endTag(null, "NetType"); serializer.startTag(null,
             * "LAC"); serializer.text(task.td.lac); serializer.endTag(null,
             * "LAC"); serializer.startTag(null, "CI");
             * serializer.text(task.td.ci); serializer.endTag(null, "CI");
             * serializer.startTag(null, "Fieldstrength");
             * serializer.text(task.td.fieldstrength); serializer.endTag(null,
             * "Fieldstrength"); serializer.startTag(null, "RSSI");
             * serializer.text(task.td.rssi); serializer.endTag(null, "RSSI");
             * serializer.startTag(null, "BER"); serializer.text(task.td.ber);
             * serializer.endTag(null, "BER"); serializer.endTag(null, "TD");
             * 
             * serializer.startTag(null, "WLAN"); serializer.startTag(null,
             * "NetType"); serializer.text(task.wlan.netType);
             * serializer.endTag(null, "NetType"); serializer.startTag(null,
             * "APSource"); serializer.text(task.wlan.apSource);
             * serializer.endTag(null, "APSource"); serializer.startTag(null,
             * "SSID"); serializer.text(task.wlan.ssid); serializer.endTag(null,
             * "SSID"); serializer.startTag(null, "BSSID");
             * serializer.text(task.wlan.bssid); serializer.endTag(null,
             * "BSSID"); serializer.startTag(null, "Cap");
             * serializer.text(task.wlan.cap); serializer.endTag(null, "Cap");
             * serializer.startTag(null, "Freq");
             * serializer.text(task.wlan.freq); serializer.endTag(null, "Freq");
             * serializer.startTag(null, "Fieldstrength");
             * serializer.text(task.wlan.fieldstrength); serializer.endTag(null,
             * "Fieldstrength"); serializer.startTag(null, "APsignal");
             * serializer.text(task.wlan.apSignal); serializer.endTag(null,
             * "APsignal"); serializer.startTag(null, "Radiosignal");
             * serializer.text(task.wlan.radioSignal); serializer.endTag(null,
             * "Radiosignal"); serializer.startTag(null, "Samefrequency");
             * serializer.text(task.wlan.Samefrequency); serializer.endTag(null,
             * "Samefrequency"); serializer.endTag(null, "WLAN");
             */

            serializer.endTag(null, "TestResultInfo");
            serializer.endTag(null, "Root");
            serializer.endDocument();
            // write xml data into the FileOutputStream
            serializer.flush();
            // finally we close the file stream
            fileos.close();
        } catch (Exception e) {
            Log.e("XmlFileCreator", "生成XML文件出错：", e);
            return null;
        }
        return fileName;
    }

    @Deprecated
    public final List<PingTask> parsePingTask(String input, Task t) {
        List<PingTask> tasks = new ArrayList<PingTask>();
        if (!StringUtils.isEmpty(input)) {
            String[] s = input.split(";");
            PingTask task = null;
            if (s.length > 0) {
                for (String e : s) {
                    task = t.newPingTask(e);
                    tasks.add(task);
                }
            } else {
                tasks.add(t.newPingTask(input));
            }
        }
        return tasks;
    }

    @Deprecated
    public final List<HttpTask> parseHttpTask(String input, Task t) {
        List<HttpTask> tasks = new ArrayList<HttpTask>();
        if (!StringUtils.isEmpty(input)) {
            String[] s = input.split(";");
            HttpTask task = null;
            if (s.length > 0) {
                for (String e : s) {
                    task = t.newHttpTask(e);
                    tasks.add(task);
                }
            } else {
                tasks.add(t.newHttpTask(input));
            }
        }
        return tasks;
    }

    @Deprecated
    public final List<FTPTask> parseFTPTask(String input, Task t) {
        List<FTPTask> tasks = new ArrayList<FTPTask>();
        if (!StringUtils.isEmpty(input)) {
            String[] s = input.split(";");
            FTPTask task = null;
            if (s.length > 0) {
                for (String e : s) {
                    task = t.newFTPTask(e);
                    tasks.add(task);
                }
            } else {
                tasks.add(t.newFTPTask(input));
            }
        }
        return tasks;
    }

}
